package org.apogee.mil.client.main.pages.admin.forms.group;

import java.util.ArrayList;

import org.apogee.mil.client.factories.ServerServiceFactory;
import org.apogee.mil.client.utils.Session;
import org.apogee.mil.shared.Constants.DisplayFormat;
import org.apogee.mil.shared.Constants.GroupFields;
import org.apogee.mil.shared.User;

import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.store.Record;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.CheckBox;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.grid.CellEditor;
import com.extjs.gxt.ui.client.widget.grid.CheckColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnData;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;
import com.extjs.gxt.ui.client.widget.grid.RowEditor;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Widget;

public class GroupComponent implements IsWidget {

	private ColumnModel cm;
	private Grid<BaseModel> grid;
	private ListStore<BaseModel> store = new ListStore<BaseModel>();
	private GroupContainer parent;
	private User currentUser;

	public GroupComponent(GroupContainer groupContainer) {
		this.currentUser = ServerServiceFactory.getUser(Session.getSessionId());
		this.parent = groupContainer;
	}

	@Override
	public Widget asWidget() {

		final ContentPanel cp = new ContentPanel();
		cp.setHeading("Groups");
		cp.setWidth(260);

		ServerServiceFactory.getAdminService(currentUser.getSessionId()).getGroups(new AsyncCallback<ArrayList<BaseModel>>() {

			@Override
			public void onSuccess(ArrayList<BaseModel> result) {
				if (result.size() == 0) {
					MessageBox.alert("Error", "Unable to get the list of groups", null);
					return;
				}
				store.removeAll();
				store.add(result);

			}

			@Override
			public void onFailure(Throwable caught) {
				MessageBox.alert("Error", "Unable to get the list of groups\n"+caught.getMessage(), null);
			}
		});


		GridCellRenderer<BaseModel> renderer = new GridCellRenderer<BaseModel>() {

			@Override
			public Object render(BaseModel model, String property, ColumnData config,
					int rowIndex, int colIndex, ListStore<BaseModel> store,
					Grid<BaseModel> grid) {

				String val = (String) (model.get(property) == null ? "No Tests..." : model.get(property));
				return "<span qtitle='" + cm.getColumnById(property).getHeader() + "' qtip='" + val  
						+ "' style='font-weight: bold;color: #5d8aa8'>" + val + "</span>";
			}
		};

		ArrayList<ColumnConfig> configs = new ArrayList<ColumnConfig>();


		ColumnConfig column = new ColumnConfig();
		column.setId(GroupFields.GROUP_ID);
		column.setHeader("Group Id");
		column.setRowHeader(true);
		column.setWidth(60);
		column.setRenderer(renderer);
		column.setEditor(new CellEditor(new TextField<Integer>()));
		configs.add(column);

		column = new ColumnConfig();
		column.setId(GroupFields.GROUP_NAME);
		column.setHeader("Group Name");
		column.setRowHeader(true);
		column.setWidth(140);
		column.setRenderer(renderer);
		column.setEditor(new CellEditor(new TextField<Integer>()));
		configs.add(column);
		
		
		CheckColumnConfig delColumn = new CheckColumnConfig(DisplayFormat.DELETE, "Delete", 50);
		CellEditor delColEditor = new CellEditor(new CheckBox());
		delColumn.setEditor(delColEditor);
		configs.add(delColumn);
		

		final RowEditor<BaseModel> re = new RowEditor<BaseModel>();

		cm = new ColumnModel(configs);

		grid = new Grid<BaseModel>(store, cm);
		grid.setBorders(true);
		grid.setColumnLines(true);
		grid.getAriaSupport().setLabelledBy(cp.getHeader().getId()+"-label");
		grid.setSize(260, 200);
		grid.addPlugin(re);

		ToolBar tb = new ToolBar();
		Button add = new Button("Add Group");
		add.addSelectionListener(new SelectionListener<ButtonEvent>() {

			@Override
			public void componentSelected(ButtonEvent ce) {
				BaseModel bm = new BaseModel();
				bm.set(DisplayFormat.NEW, DisplayFormat.NEW);
				re.stopEditing(false);
				store.insert(bm, store.getCount());
				re.startEditing(store.indexOf(bm), true);

			}
		});

		tb.add(add);

		cp.setTopComponent(tb);
		cp.setButtonAlign(HorizontalAlignment.CENTER);
		cp.addButton(new Button("Reset", new SelectionListener<ButtonEvent>() {  

			@Override  
			public void componentSelected(ButtonEvent ce) {  
				store.rejectChanges();  
			}  
		}));  
		
		
		cp.addButton(new Button("Save", new SelectionListener<ButtonEvent>() {  

			@Override  
			public void componentSelected(ButtonEvent ce) {

				ArrayList<Record> changes = (ArrayList<Record>) store.getModifiedRecords();
				ArrayList<BaseModel> changed = new ArrayList<BaseModel>();
				for (Record r : changes) {
					BaseModel bm = new BaseModel();
					for (String s : r.getPropertyNames()) {
						bm.set(s, r.get(s));
					}
					
					if (bm.get(DisplayFormat.DELETE) != null && bm.get(DisplayFormat.DELETE).toString().toLowerCase().equals("true")) {
						store.remove((BaseModel) r.getModel());
					}
					
					changed.add(bm);
				}
								
				
				ServerServiceFactory.getAdminService(currentUser.getSessionId()).updateGroups(changed, new AsyncCallback<Boolean>() {
					
					@Override
					public void onSuccess(Boolean result) {
						if (result == false) {
							MessageBox.alert("Error", "Unable to update groups", null);
							store.rejectChanges(); 
							return;
						}
						Info.display("Success", "Groups updated");
						try {
							parent.resetGroupConfiguration();
						} catch (Exception err) {
							
						}
						store.commitChanges(); 
						
					}
					
					@Override
					public void onFailure(Throwable caught) {
						MessageBox.alert("Error", "Unable to update groups\n"+caught.getMessage(), null);
						store.rejectChanges(); 
						
					}
				}); 
			}  
		}));


		cp.add(grid);

		return cp;
	}

}
